import { useState, useEffect, useLayoutEffect, useRef } from "preact/hooks";
import { getTime } from "../utilities";
import { toast } from "../signals";
import { settings } from "../settings";
import { themeNames } from "../engines";

const totalDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

function getTotalDays(year, month) {
  let yearAdd = 0;
  year % 4 === 0 && yearAdd++;
  year % 100 === 0 && yearAdd++;
  year % 400 === 0 && yearAdd++;
  return totalDays[month - 1] + (month === 2 ? yearAdd % 2 : 0);
}

const [todayYear, todayMonth, today] = getTime().map((v) =>
  Number.parseInt(v, 10),
);

const Calendar = () => {
  const [year, setYear] = useState(todayYear);
  const [month, setMonth] = useState(todayMonth);
  const [day, setDay] = useState(today);
  const lockRef = useRef(false);
  const [grids, setGrids] = useState([]);
  const yearReference = useRef(todayYear);
  const monthReference = useRef(todayMonth);
  const dayReference = useRef(today);

  useEffect(() => {
    const id = setInterval(() => {
      const [currentYear, currentMonth, current] = getTime().map((v) =>
        Number.parseInt(v, 10),
      );
      yearReference.current = currentYear;
      monthReference.current = currentMonth;
      dayReference.current = current;
      if (!lockRef.current) {
        setYear(currentYear);
        setMonth(currentMonth);
        setDay(current);
      }
    }, 500);
    return () => clearInterval(id);
  }, []);

  useLayoutEffect(() => {
    if (year < 100 || year > 3999) {
      toast("不支持");
      setYear(2000);
      return;
    }
    const padding =
      getTime(new Date(year, month - 1, 1))[11] -
      (settings.value.widget.calendarMonday ? 1 : 0);
    const grid = Array.from({ length: padding }).fill(<div />);
    const total = getTotalDays(year, month);
    for (let index = 1; index <= total; ++index) {
      const data = getTime(new Date(year, month - 1, index));
      const ny = data[7];
      const nr = data[8];
      const xq = data[11];
      const nl = nr === "初一" ? ny : nr;

      const currentDay = lockRef.current ? dayReference.current : day;

      const isToday =
        year === yearReference.current &&
        month === monthReference.current &&
        index === currentDay;

      const isPast =
        year * 372 + month * 31 + index <
        yearReference.current * 372 + monthReference.current * 31 + currentDay;

      let normalText =
        xq % 6 === 0
          ? themeNames[settings.value.widget.calendarWeekend][3]
          : "";
      if (isPast && settings.value.widget.calendarPast) {
        normalText += " opacity-50";
      }
      grid.push(
        <div
          class={`flex flex-col place-items-center ${isToday ? themeNames[settings.value.widget.calendarToday][3] : normalText}`}
        >
          <div class="text-base">{index}</div>
          <div class="-mt-1 pb-1 text-[8px]">{nl}</div>
        </div>,
      );
    }
    setGrids([...grid]);
  }, [year, month, day, settings.value]);

  return (
    <div class="card w-69">
      <div class="card-body **:font-mono **:font-bold">
        <div class="card-actions *:btn-xs *:btn-ghost *:btn-primary m-auto place-items-center">
          <button
            class="btn"
            onClick={() => {
              lockRef.current = true;
              setYear(year - 1);
            }}
          >
            &lt;&lt;
          </button>
          <button
            class="btn"
            onClick={() => {
              lockRef.current = true;
              setYear(month === 1 ? year - 1 : year);
              setMonth(month === 1 ? 12 : month - 1);
            }}
          >
            &lt;
          </button>
          <button
            class="btn"
            onClick={() => {
              lockRef.current = false;
              setYear(todayYear);
              setMonth(todayMonth);
            }}
          >
            {year}-{String(month).padStart(2, "0")}
          </button>
          <button
            class="btn"
            onClick={() => {
              lockRef.current = true;
              setYear(month === 12 ? year + 1 : year);
              setMonth(month === 12 ? 1 : month + 1);
            }}
          >
            &gt;
          </button>
          <button
            class="btn"
            onClick={() => {
              lockRef.current = true;
              setYear(year + 1);
            }}
          >
            &gt;&gt;
          </button>
        </div>
        <div class="grid grid-cols-7">{grids}</div>
      </div>
    </div>
  );
};

export default Calendar;
